package edu.hubu.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import net.moon.jpa.model.BaseEntity;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "student_course")
//逻辑删除注解，删除sql变成了update
@SQLDelete(sql = "update student_course set student_course_is_deleted = true where student_course_id = ?")
//where条件带上了逻辑删除条件
@Where(clause = "student_course_is_deleted = false")
@ApiModel("学生课程")
@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
public class StudentCourse extends BaseEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "snowflakeId")
    @GenericGenerator(name = "snowflakeId", strategy = "edu.hubu.commons.SnowflakeId", parameters = {@org.hibernate.annotations.Parameter(name = "prefix", value = "STUDENT-COURSE")})
    @Column(name = "student_course_id")
    @ApiModelProperty(value = "学生课程号", position = 1)
    private String studentCourseId;

    @Column(name = "student_course_effective_date")
    @ApiModelProperty(value = "课程开课时间", position = 10)
    private Date studentCourseEffectiveDate;

    @Column(name = "student_course_expiry_date")
    @ApiModelProperty(value = "课程结课时间", position = 11)
    private Date studentCourseExpiryDate;

    @Column(name = "student_course_strategy")
    @ApiModelProperty(value = "学生课程安排策略，0为每周都上，1为单周，2为双周", position = 3)
    private int studentCourseStrategy;

    @Column(name = "student_course_week_day")
    @ApiModelProperty(value = "学生课程上课是在周几，范围0~6", position = 4)
    private int studentCourseWeekDay;

    @Column(name = "student_course_student_nums")
    @ApiModelProperty(value = "课程的选课人数", position = 4)
    private int studentCourseStudentNums;

    @Column(name = "student_course_is_forbidden")
    @ApiModelProperty(value = "学生课程是否被禁用", position = 6)
    private boolean studentCourseIsForbidden = false;

    @Column(name = "student_course_is_deleted")
    @ApiModelProperty(value = "学生课程是否被删除", position = 7)
    private boolean studentCourseIsDeleted = false;

    @ManyToOne(targetEntity = Course.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "student_course_course_id", referencedColumnName = "course_id")
    @ApiModelProperty(value = "课程ID", position = 7)
    private Course course;

    @ManyToOne(targetEntity = Credit.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "student_course_credit_id", referencedColumnName = "credit_id")
    @ApiModelProperty(value = "课程学分", position = 4)
    private Credit credit;

    @ManyToOne(targetEntity = CourseHour.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "student_course_course_hour_id", referencedColumnName = "course_hour_id")
    @ApiModelProperty(value = "课程学时", position = 5)
    private CourseHour courseHour;

    @ManyToOne(targetEntity = Major.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "student_course_major_id", referencedColumnName = "major_id")
    @ApiModelProperty(value = "开课专业", position = 7)
    private Major major;

    @ManyToOne(targetEntity = CourseType.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "student_course_type_id", referencedColumnName = "course_type_id")
    @ApiModelProperty(value = "课程类型", position = 9)
    private CourseType courseType;

    @OneToOne(targetEntity = Book.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "student_course_book_id", referencedColumnName = "book_id")
    @ApiModelProperty(value = "课程书籍", position = 6)
    private Book book;

    @ManyToMany(targetEntity = CourseDailyTime.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinTable(name = "student_course_course_time", joinColumns = {@JoinColumn(name = "student_course_course_time_student_course_id", referencedColumnName = "student_course_id")}, inverseJoinColumns = @JoinColumn(name = "student_course_course_time_course_time_id", referencedColumnName = "course_time_id"))
    @ApiModelProperty(hidden = true)
    private List<CourseDailyTime> studentCourseTime = new ArrayList<>();

    @ManyToMany(mappedBy = "studentCourses", fetch = FetchType.LAZY)
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    private List<Student> students = new ArrayList<>();

    @ManyToMany(targetEntity = Teacher.class, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinTable(name = "student_course_teacher", joinColumns = {@JoinColumn(name = "student_course_teacher_course_id", referencedColumnName = "student_course_id")}, inverseJoinColumns = @JoinColumn(name = "student_course_teacher_teacher_id", referencedColumnName = "user_sid"))
    @ApiModelProperty(hidden = true)
    private List<Teacher> teachers = new ArrayList<>();

    public StudentCourse(String studentCourseId, Date studentCourseEffectiveDate, Date studentCourseExpiryDate, int studentCourseStrategy, int studentCourseWeekDay, int studentCourseStudentNums, boolean studentCourseIsForbidden, boolean studentCourseIsDeleted, Course course, Credit credit, CourseHour courseHour, Major major, CourseType courseType, Book book, List<CourseDailyTime> studentCourseTime, List<Student> students, List<Teacher> teachers) {
        this.studentCourseId = studentCourseId;
        this.studentCourseEffectiveDate = studentCourseEffectiveDate;
        this.studentCourseExpiryDate = studentCourseExpiryDate;
        this.studentCourseStrategy = studentCourseStrategy;
        this.studentCourseWeekDay = studentCourseWeekDay;
        this.studentCourseStudentNums = studentCourseStudentNums;
        this.studentCourseIsForbidden = studentCourseIsForbidden;
        this.studentCourseIsDeleted = studentCourseIsDeleted;
        this.course = course;
        this.credit = credit;
        this.courseHour = courseHour;
        this.major = major;
        this.courseType = courseType;
        this.book = book;
        this.studentCourseTime = studentCourseTime;
        this.students = students;
        this.teachers = teachers;
    }

    public StudentCourse() {
    }

    public static StudentCourseBuilder builder() {
        return new StudentCourseBuilder();
    }

    public String getStudentCourseId() {
        return this.studentCourseId;
    }

    public Date getStudentCourseEffectiveDate() {
        return this.studentCourseEffectiveDate;
    }

    public Date getStudentCourseExpiryDate() {
        return this.studentCourseExpiryDate;
    }

    public int getStudentCourseStrategy() {
        return this.studentCourseStrategy;
    }

    public int getStudentCourseWeekDay() {
        return this.studentCourseWeekDay;
    }

    public int getStudentCourseStudentNums() {
        return this.studentCourseStudentNums;
    }

    public boolean isStudentCourseIsForbidden() {
        return this.studentCourseIsForbidden;
    }

    public boolean isStudentCourseIsDeleted() {
        return this.studentCourseIsDeleted;
    }

    public Course getCourse() {
        return this.course;
    }

    public Credit getCredit() {
        return this.credit;
    }

    public CourseHour getCourseHour() {
        return this.courseHour;
    }

    public Major getMajor() {
        return this.major;
    }

    public CourseType getCourseType() {
        return this.courseType;
    }

    public Book getBook() {
        return this.book;
    }

    public List<CourseDailyTime> getStudentCourseTime() {
        return this.studentCourseTime;
    }

    public List<Student> getStudents() {
        return this.students;
    }

    public List<Teacher> getTeachers() {
        return this.teachers;
    }

    public void setStudentCourseId(String studentCourseId) {
        this.studentCourseId = studentCourseId;
    }

    public void setStudentCourseEffectiveDate(Date studentCourseEffectiveDate) {
        this.studentCourseEffectiveDate = studentCourseEffectiveDate;
    }

    public void setStudentCourseExpiryDate(Date studentCourseExpiryDate) {
        this.studentCourseExpiryDate = studentCourseExpiryDate;
    }

    public void setStudentCourseStrategy(int studentCourseStrategy) {
        this.studentCourseStrategy = studentCourseStrategy;
    }

    public void setStudentCourseWeekDay(int studentCourseWeekDay) {
        this.studentCourseWeekDay = studentCourseWeekDay;
    }

    public void setStudentCourseStudentNums(int studentCourseStudentNums) {
        this.studentCourseStudentNums = studentCourseStudentNums;
    }

    public void setStudentCourseIsForbidden(boolean studentCourseIsForbidden) {
        this.studentCourseIsForbidden = studentCourseIsForbidden;
    }

    public void setStudentCourseIsDeleted(boolean studentCourseIsDeleted) {
        this.studentCourseIsDeleted = studentCourseIsDeleted;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public void setCredit(Credit credit) {
        this.credit = credit;
    }

    public void setCourseHour(CourseHour courseHour) {
        this.courseHour = courseHour;
    }

    public void setMajor(Major major) {
        this.major = major;
    }

    public void setCourseType(CourseType courseType) {
        this.courseType = courseType;
    }

    public void setBook(Book book) {
        this.book = book;
    }

    public void setStudentCourseTime(List<CourseDailyTime> studentCourseTime) {
        this.studentCourseTime = studentCourseTime;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }

    public void setTeachers(List<Teacher> teachers) {
        this.teachers = teachers;
    }

    public static class StudentCourseBuilder {
        private String studentCourseId;
        private Date studentCourseEffectiveDate;
        private Date studentCourseExpiryDate;
        private int studentCourseStrategy;
        private int studentCourseWeekDay;
        private int studentCourseStudentNums;
        private boolean studentCourseIsForbidden;
        private boolean studentCourseIsDeleted;
        private Course course;
        private Credit credit;
        private CourseHour courseHour;
        private Major major;
        private CourseType courseType;
        private Book book;
        private List<CourseDailyTime> studentCourseTime;
        private List<Student> students;
        private List<Teacher> teachers;

        StudentCourseBuilder() {
        }

        public StudentCourseBuilder studentCourseId(String studentCourseId) {
            this.studentCourseId = studentCourseId;
            return this;
        }

        public StudentCourseBuilder studentCourseEffectiveDate(Date studentCourseEffectiveDate) {
            this.studentCourseEffectiveDate = studentCourseEffectiveDate;
            return this;
        }

        public StudentCourseBuilder studentCourseExpiryDate(Date studentCourseExpiryDate) {
            this.studentCourseExpiryDate = studentCourseExpiryDate;
            return this;
        }

        public StudentCourseBuilder studentCourseStrategy(int studentCourseStrategy) {
            this.studentCourseStrategy = studentCourseStrategy;
            return this;
        }

        public StudentCourseBuilder studentCourseWeekDay(int studentCourseWeekDay) {
            this.studentCourseWeekDay = studentCourseWeekDay;
            return this;
        }

        public StudentCourseBuilder studentCourseStudentNums(int studentCourseStudentNums) {
            this.studentCourseStudentNums = studentCourseStudentNums;
            return this;
        }

        public StudentCourseBuilder studentCourseIsForbidden(boolean studentCourseIsForbidden) {
            this.studentCourseIsForbidden = studentCourseIsForbidden;
            return this;
        }

        public StudentCourseBuilder studentCourseIsDeleted(boolean studentCourseIsDeleted) {
            this.studentCourseIsDeleted = studentCourseIsDeleted;
            return this;
        }

        public StudentCourseBuilder course(Course course) {
            this.course = course;
            return this;
        }

        public StudentCourseBuilder credit(Credit credit) {
            this.credit = credit;
            return this;
        }

        public StudentCourseBuilder courseHour(CourseHour courseHour) {
            this.courseHour = courseHour;
            return this;
        }

        public StudentCourseBuilder major(Major major) {
            this.major = major;
            return this;
        }

        public StudentCourseBuilder courseType(CourseType courseType) {
            this.courseType = courseType;
            return this;
        }

        public StudentCourseBuilder book(Book book) {
            this.book = book;
            return this;
        }

        public StudentCourseBuilder studentCourseTime(List<CourseDailyTime> studentCourseTime) {
            this.studentCourseTime = studentCourseTime;
            return this;
        }

        public StudentCourseBuilder students(List<Student> students) {
            this.students = students;
            return this;
        }

        public StudentCourseBuilder teachers(List<Teacher> teachers) {
            this.teachers = teachers;
            return this;
        }

        public StudentCourse build() {
            return new StudentCourse(studentCourseId, studentCourseEffectiveDate, studentCourseExpiryDate, studentCourseStrategy, studentCourseWeekDay, studentCourseStudentNums, studentCourseIsForbidden, studentCourseIsDeleted, course, credit, courseHour, major, courseType, book, studentCourseTime, students, teachers);
        }

        public String toString() {
            return "StudentCourse.StudentCourseBuilder(studentCourseId=" + this.studentCourseId + ", studentCourseEffectiveDate=" + this.studentCourseEffectiveDate + ", studentCourseExpiryDate=" + this.studentCourseExpiryDate + ", studentCourseStrategy=" + this.studentCourseStrategy + ", studentCourseWeekDay=" + this.studentCourseWeekDay + ", studentCourseStudentNums=" + this.studentCourseStudentNums + ", studentCourseIsForbidden=" + this.studentCourseIsForbidden + ", studentCourseIsDeleted=" + this.studentCourseIsDeleted + ", course=" + this.course + ", credit=" + this.credit + ", courseHour=" + this.courseHour + ", major=" + this.major + ", courseType=" + this.courseType + ", book=" + this.book + ", studentCourseTime=" + this.studentCourseTime + ", students=" + this.students + ", teachers=" + this.teachers + ")";
        }
    }
}
